// 13_threads.rs
// Rust 线程使用教程

use std::thread;
use std::time::Duration;
use std::sync::{Arc, Mutex};

fn main() {
    // 1. 创建线程
    println!("=== 1. 创建线程 ===");
    
    // 使用 thread::spawn 创建新线程
    let handle = thread::spawn(|| {
        for i in 1..10 {
            println!("线程中打印: {}", i);
            thread::sleep(Duration::from_millis(1));
        }
    });
    
    // 在主线程中执行
    for i in 1..5 {
        println!("主线程中打印: {}", i);
        thread::sleep(Duration::from_millis(1));
    }
    
    // 等待子线程执行完成
    handle.join().unwrap();
    
    // 2. 线程间数据传递
    println!("\n=== 2. 线程间数据传递 ===");
    
    let v = vec![1, 2, 3];
    
    // move 关键字将所有权转移给新线程
    let handle = thread::spawn(move || {
        println!("在线程中访问 vector: {:?}", v);
    });
    // println!("主线程访问 vector: {:?}", v);//不能访问
    handle.join().unwrap();
    
    // 3. 使用 Arc 共享数据
    println!("\n=== 3. 使用 Arc 共享数据 ===");
    
    let counter = Arc::new(Mutex::new(0));
    let mut handles = vec![];
    
    for _ in 0..10 {
        let counter = Arc::clone(&counter);
        let handle = thread::spawn(move || {
            let mut num = counter.lock().unwrap();
            *num += 1;
        });
        handles.push(handle);
    }
    
    for handle in handles {
        handle.join().unwrap();
    }
    
    println!("结果: {}", *counter.lock().unwrap());
    
    // 4. 线程恐慌处理
    println!("\n=== 4. 线程恐慌处理 ===");
    
    let handle = thread::spawn(|| {
        panic!("线程中发生恐慌！");
    });
    
    match handle.join() {
        Ok(_) => println!("线程正常结束"),
        Err(_) => println!("线程发生恐慌，但已被捕获"),
    }
    
    // 5. 线程命名
    println!("\n=== 5. 线程命名 ===");
    
    let builder = thread::Builder::new()
        .name("我的自定义线程".to_string())
        .stack_size(1024 * 1024); // 1MB 栈大小
    
    let handle = builder.spawn(|| {
        println!("当前线程名称: {:?}", thread::current().name());
    }).unwrap();
    
    handle.join().unwrap();
    
    // 6. 线程本地存储
    println!("\n=== 6. 线程本地存储 ===");
    
    thread_local!(static THREAD_LOCAL: u32 = 5);
    
    THREAD_LOCAL.with(|value| {
        println!("线程本地存储值: {}", value);
    });
    
    let handle = thread::spawn(|| {
        THREAD_LOCAL.with(|value| {
            println!("另一个线程中的本地存储值: {}", value);
        });
    });
    
    handle.join().unwrap();
    
    println!("\n线程教程完成！");
}